


#include "net.h"



void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
{
    struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
    ipaddr_t src_ip;
    int eth_hdr_size;
    struct net_gd *gd = net_get_gd();

    switch (icmph->type) {

    case ICMP_ECHO_REPLY:
        src_ip = net_read_ip((void *)&ip->ip_src);
        if (src_ip == gd->ping_ip)
            gd->flag.ping_success = 1;
        return;

    case ICMP_ECHO_REQUEST:
        eth_hdr_size = net_update_ether(et, et->src, PROT_IP);
        
        /*
        net_debug("ICMP ECHO Request, return %d bytes %d",
            eth_hdr_size + len, IP_HDR_SIZE);*/

        ip->ip_sum = 0;
        ip->ip_off = 0;
        net_copy_ip((void *)&ip->ip_dst, &ip->ip_src);
        net_copy_ip((void *)&ip->ip_src, &gd->ipaddr);
        ip->ip_sum = ~net_cksum((qe_u8 *)ip, IP_HDR_SIZE >> 1);
        icmph->type = ICMP_ECHO_REPLY;
        icmph->checksum = 0;
        icmph->checksum = ~net_cksum((qe_u8 *)icmph,
            (len - IP_HDR_SIZE) >> 1);
        //net_debug("send icmp replay");
        net_send_packet((qe_u8 *)et, eth_hdr_size + len);
        return;

    default:
        //net_err("unknown type 0x%x", icmph->type);
        return;
    }
}
